<template>
  <div class="popupSelect-container" :class="{'page-container': isPage}">
    <div class="el-select" @click.stop="openDialog" @mouseenter="inputHovering = true"
      @mouseleave="inputHovering = false" v-if="showInput" v-show="!isPage">
      <div class="el-select__tags" v-if="multiple" ref="tags" :style="{
        'max-width': tagsList && tagsList.length > 0 ? 'calc(90%)' : '',
        width: '92%',
        cursor: 'pointer',
      }">
        <span v-if="collapseTags && tagsList.length">
          <el-tag :closable="!selectDisabled" type="info" @close="deleteTag($event, 0)" disable-transitions>
            <span class="el-select__tags-text">{{ tagsList[0] }}</span>
          </el-tag>
          <el-tag v-if="tagsList.length > 1" :closable="false" type="info" disable-transitions>
            <span class="el-select__tags-text">+ {{ tagsList.length - 1 }}</span>
          </el-tag>
        </span>
        <transition-group @after-leave="resetInputHeight" v-if="!collapseTags && tagsList.length">
          <el-tag v-for="(item, i) in tagsList" :key="item" :closable="!(selectedData[i] && selectedData[i].forbidden || selectDisabled)" type="info"
            @close="deleteTag($event, i)" disable-transitions>
            <span class="el-select__tags-text">{{ item }}</span>
          </el-tag>
        </transition-group>
      </div>
      <el-input ref="reference" v-model="innerValue" type="text"
        :placeholder="tagsList && tagsList.length ? '' : currentPlaceholder" :disabled="selectDisabled" readonly
        :validate-event="false" :tabindex="multiple ? '-1' : null" :title="innerValue">
        <template #suffix>
          <el-icon v-if="!showClose">
            <ArrowDown />
          </el-icon>
          <el-icon v-if="showClose" @click.stop="handleClearClick">
            <CircleClose />
          </el-icon>
        </template>
      </el-input>
    </div>
    <el-dialog :title="title" :close-on-click-modal="false" v-model="visible" draggable
      class="ZHLX-dialog ZHLX-dialog_center transfer-dialog common-dialog" lock-scroll width="770px"
      :modal-append-to-body="false" @open="resetTreeChecked()" @close="onClose" style="display: block"
      :modal="!isPage" :show-close="!isPage" :close-on-press-escape="!isPage" :append-to-body="!isPage">
      <el-tabs v-show="tabList.length > 1" v-model="activeName" :class="{ 'hasSys-tab': hasSys }" style="padding: 0px 0px 10px;"
        @tab-change="handleTabChange">
        <el-tab-pane :label="item.fullname" :name="item.name" v-for="(item, index) in tabList"
          :key="index" style="margin: 0"></el-tab-pane>
      </el-tabs>
      <div class="transfer__body" :style="{'padding-top': tabList.length > 1 ? 0 : '8px'}">
        <div class="transfer-pane">
          <div class="transfer-pane__tools" v-if="activeName !== 'relativeRelation'">
            <div class="check-all-btn" v-if="choosePerson != 'organize'">
              <el-checkbox v-model="searchAll" label="全部" size="small" @change="handleSearchAll" />
            </div>
            <el-input placeholder="请输入关键词查询" v-model="keyword" @keyup.enter="searchClick" clearable
              class="search-input">
              <template #append>
                <el-icon @click="searchClick">
                  <Search />
                </el-icon>
              </template>
            </el-input>
          </div>
          <div v-else class="relativeRelation-title"> 
            <span>相对关系</span>
          </div>
          <div class="transfer-pane__wrap" style="height: 430px">
            <div class="transfer-pane__body btn_top" :style="{ height: setDeptHeight + 'px !important' }"
              v-show="showDept">
              <template v-if="activeName">
                <el-tree-v2 ref="tree" :height="setDeptHeight" :data="treeData" :props="defaultProps"
                  :check-strictly="true" :default-checked-keys="selectedIds" :expand-on-click-node="false" 
                  @node-click="handleNodeClick" @check="handleCheckClick" @node-expand="loadNodeData" :current-node-key="currentNodeKey"
                  :show-checkbox="true" v-loading="loading" lazy :filter-method="(this.activeName === 'role' || this.activeName === 'post') && filterMethod">
                  <template #default="{ node, data }">
                    <span class="custom-tree-node">
                      <el-icon class="is-loading" v-if="data.childLoading" style="margin-right: 4px;">
                        <Loading />
                      </el-icon>
                      <SvgIcon :icon-class="getIconByType(data.objectType, data.tag)" :size='14' color='#979797'
                        v-if="data.name" />
                      <span class="text" :title="data.organizeDesc || data.deptName">{{ data.name }}</span>
                      <el-tag v-if="data.id === currentNodeKey && activeName === 'relativeRelation' " type="success" size="mini">当前选中</el-tag>
                      <el-tag v-if="data.id === currentKey && activeName != 'relativeRelation' && choosePerson != 'organize'" type="success" size="mini">当前选中</el-tag>
                    </span>
                  </template>
                </el-tree-v2>
              </template>

            </div>
            <div class="transfer-pane__title" v-if="choosePerson != 'organize'"
              style="display: flex; justify-content: space-between;">
              <!-- 相对关系下方人员title替换 -->
              <span style="flex-shrink: 0;padding-left: 10px;" v-if="activeName !== 'relativeRelation'">
                <el-checkbox v-model="selectAllPerson" label="全选" size="small" @change="handleSelectAllPerson" :disabled="!userData.length || !multiple"/>
                人员
              </span>
              <span style="flex-shrink: 0;padding-left: 10px;" v-else>相对范围</span>
              <el-input placeholder="请输入关键词查询" v-model="personKeyword" @keyup.enter="getPersonPagecurrentList(1)"
                clearable class="search-input" style="width: 55%;" v-if="activeName !== 'relativeRelation' && activeName !== 'group'">
                <template #append>
                  <el-icon class="is-loading" v-if="personLoading">
                    <Loading />
                  </el-icon>
                  <el-icon @click="getPersonPagecurrentList(1)" v-else>
                    <Search />
                  </el-icon>
                </template>
              </el-input>
              <div class="transfer-btn-list">
                <div class="transfer-btn top" @click="handleClose(1)" v-show="showDept"><i></i></div>
                <div class="transfer-btn bottom" @click="handleClose(2)" v-show="showPerson"><i></i></div>
              </div>
            </div>
            <div class="transfer-pane__body btn_bottom" v-if="choosePerson != 'organize'"
              :style="{ height: setPersonHeight + 'px !important' }" v-show="showPerson">
              <el-tree-v2 ref="personTree" v-if="userData" class="user-list"
                :height="setPersonHeight" :data="userData"
                :check-strictly="true" :default-checked-keys="selectedIds" :expand-on-click-node="false"
                :check-on-click-node="true" :props="defaultPersonProps" @check="handleCheckClickPerson" @node-click="handleNodeClickClickPerson"
                :show-checkbox="true" node-key="id" v-loading="personLoading">
                <template #default="{ node, data }">
                  <span class="custom-tree-node">
                    <SvgIcon :icon-class="getIconByType(data.objectType)" :size='14' color='#979797' />
                    <span class="text" :title="data.organizeDesc || data.deptName">{{ data.name }}</span>
                    <span class="text" :title="data.userAlias" v-if="data.userAlias">({{ data.userAlias }})</span>
                  </span>
                </template>
              </el-tree-v2>
              <!-- <div v-if="userData.length > 0 && activeName != 'circulation'" class="text-center pointer" @click="getPersonPagecurrentList">
                <span v-if="typeof pageTotal === 'number' && pageTotal !== userData.length">加载更多</span>
              </div> -->
            </div>
          </div>
        </div>
        <div class="transfer-pane">
          <div class="transfer-pane__tools">
            <span>已选({{ selectedData.length || 0 }})</span>
            <el-input placeholder="请输入关键词查询" v-model="selectedKeyword" @keyup.enter="getSelectedList(selectedKeyword)"
              clearable class="search-input" style="width: 60%;">
              <template #append>
                <el-icon @click="getSelectedList(selectedKeyword)">
                  <Search />
                </el-icon>
              </template>
            </el-input>
            <el-button @click="removeAll" link class="removeAllBtn">清空列表
            </el-button>
          </div>
          <div class="transfer-pane__body right-pane" style="height: 430px !important;" v-loading="selectedLoading">
            <template v-if="selectedData.length">
              <el-scrollbar>
                <div v-for="(item, index) in selectedData" :key="index" class="selected-item-user"
                  v-show="!item.isHide">
                  <div class="selected-item-main">
                    <el-avatar>
                      <SvgIcon :icon-class="getIconByType(item.objectType, item.tag)" :size='20' color='#ffffff' />
                    </el-avatar>
                    <div class="selected-item-text">
                      <p class="name">{{ item.name }}<span v-if="item.downFlag">(包含子级)</span><span :title="item.userAlias" v-if="item.userAlias">({{ item.userAlias }})</span></p>
                      <p class="organize" v-if="item.organizeDesc || item.deptName" :title="item.organizeDesc || item.deptName">{{ item.organizeDesc || item.deptName }}</p>
                    </div>
                    <el-icon class="el-icon-delete" @click="removeData(item, index)" v-if="!item.forbidden">
                      <Delete />
                    </el-icon>
                  </div>
                </div>
                <a id="anchor"></a>
              </el-scrollbar>
            </template>
            <el-empty description="暂无数据" :image-size="120" v-else></el-empty>
          </div>
        </div>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="onClose(), setDefault(), (visible = false)">取消</el-button>
          <el-button type="primary" @click="confirm" :loading="selectedLoading">确认</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts">
import {
  getDeptTreeParent,
  getRoleListAPI,
  getPostListAPI,
  getDeptList,
  getGroupListAPI,
  getPersonListAPI,
  getRoleUserListAPI,
  getPostUserListAPI,
  getUserInfoByUserIdsAPI,
  getRelativeRelationListAPI,
  getFindRelativeRangeListAPI,
  getUserByGroupIdAPI,
  getCirculationListAPI,
  getCirculationUserAPI,
  getNoTenantUserPageAPI,
  getNoTenantUserInfoByIdsAPI,
 } from "@/api/admin/dept";
import SvgIcon from "@/components/svg-icon/index.vue";
import service from "@/utils/request";
import { deepClone } from "@/utils/util";
import { log } from "console";
export default {
  name: "commonSelect",
  components: {
    SvgIcon,
  },
  inject: {
    elForm: {
      default: "",
    },
    elFormItem: {
      default: "",
    },
    getGlobalDsv: {
      default: "",
    },
  },
  props: {
    // 组件类型
    comUse: {
      type: String,
      default: ""
    },
    // 反显数据
    modelValue: {
      type: [Array, String]
      // default: () => [],
    },
    // 占位提示
    placeholder: {
      type: String,
      default: "请选择",
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false,
    },
    // 是否多选
    multiple: {
      type: Boolean,
      default: false,
    },
    // 是否展示tag样式
    collapseTags: {
      type: Boolean,
      default: false,
    },
    // 是否可删除
    clearable: {
      type: Boolean,
      default: false,
    },
    // dialog页面模式 是否将dialog平铺展示，作为div插入到页面中
    isPage: {
      type: Boolean,
      default: false,
    },
    // 表单label
    title: {
      type: String,
      default: "选择组织",
    },
    // 选择人员类型 可选值 all(组织等和人都能选) organize(只选组织等) person(只选人)
    choosePerson: {
      type: String,
      default: 'all',
    },
    // 用户权限 可选值：department(包括组织、单位、部门) group role post relativePost relativeRelation circulation
    authorityList: {
      type: Array,
      default: () => [],
    },
    // 是否展示input输入框
    showInput: {
      type: Boolean,
      default: true,
    },
    // 返回数据类型是否为对象数组[{}],否则为['']
    isReturnData: {
      type: Boolean,
      default: false,
    },
    //组织类型 unit仅单位 / department仅部门 / object仅项目 / all全部
    organizeType: {
      type: String,
      default: "all",
    },
    //显示格式 organizePath组织全路径 / name当前名称
    displayFormat: {
      type: String,
      default: "name",
    },
    //返回数据格式 ['返回字段'] 不传默认全部返回
    formatRuleData: {
      type: Array,
      default: () => [],
    },
    // 传入部门查询全量接口
    deptUrl: {
      type: String,
      default: "",
    },
    // 跨平台时是否支持选择包含下级，为true时需要传入deptUrl
    crossPlatformDownFlag: {
      type: Boolean,
      default: false,
    },
    // 是否自动带入
    isAutoImport: {
      type: Boolean,
      default: false,
    },
    // 是否展示包含子级弹窗 默认展示
    isShowDownFlag: {
      type: Boolean,
      default: true,
    }
  },
  data() {
    return {
      // 用于tab数据
      treeData: [],
      // 用于回显存放所有数据
      allList: [],
      // 左侧搜索
      keyword: "",
      // 展示选择后的text
      innerValue: "",
      // 弹窗是否展示
      visible: false,
      // 树loading
      loading: false,
      // 人员区域loading
      personLoading: false,
      // 已选区域loading 获取反显数据
      selectedLoading: false,
      // 默认树属性
      defaultProps: {
        children: "children",
        label: "fullName",
        isLeaf: "isLeaf",
        value: "id",
      },
      // 默认人员属性
      defaultPersonProps: {
        children: "children",
        label: "name",
        isLeaf: "isLeaf",
      },
      // 已选数组对象
      selectedData: [],
      // 已选id数组
      selectedIds: [],
      // 展示已选tag类型
      tagsList: [],
      // 当前选中
      currentKey: '',
      selectedRelation: null, // 初始化选中的相对关系
      currentNodeKey: null, // 当前选中节点
      // 存放人员数组
      userData: [],
      // 人员检索
      userSearch: '',
      inputHovering: false,
      // 输入框宽度
      inputWidth: 0,
      // 输入框高度
      initialInputHeight: 0,
      // 当前tab选中类型
      activeName: "",
      // 右侧检索
      selectedKeyword: "",
      hasSys: false,
      // 勾选全部，用于查询列表接口
      searchAll: false,
      // 默认tab列表
      defaultTabList: [
        { fullname: '组织', name: 'department', },
        { fullname: '分组', name: 'group', },
        { fullname: '角色', name: 'role', },
        { fullname: '岗位', name: 'post', },
        // { fullname: '相对岗位', name: 'relativePost', },
        { fullname: '相对关系', name: 'relativeRelation', },
        { fullname: '传阅组', name: 'circulation', },
      ],
      tabList: [],
      // 分页页数
      pageCurrent: 1,
      // 分页总数
      pageTotal: 0,
      // 人员搜索参数
      personKeyword: '',
      // 是否展示组织列表
      showDept: true,
      // 是否展示人员列表
      showPerson: true,
    };
  },
  computed: {
    /**
     * 判断是否显示关闭按钮
     * @returns 如果满足以下条件则返回true，否则返回false：
     *          1. 当前组件绑定的modelValue有值且长度大于0
     *          2. 组件的clearable属性为true
     *          3. 组件的selectDisabled属性为false
     *          4. 组件的inputHovering属性为true
     */
    showClose() {
      let hasValue = this.modelValue && this.modelValue.length > 0;
      let criteria =
        this.clearable &&
        !this.selectDisabled &&
        this.inputHovering &&
        hasValue;
      return criteria;
    },
    /**
     * 获取当前占位提示
     * @returns 如果为多选且已有选中项，则返回空字符串，否则返回当前占位符
     */
    currentPlaceholder() {
      if (this.multiple && this.modelValue && this.modelValue.length) {
        return "";
      } else {
        return this.placeholder;
      }
    },
    /**
     * 判断是否禁用选择框
     * @returns 返回一个布尔值，表示是否禁用选择框
     */
    selectDisabled() {
      return this.disabled || (this.elForm || {}).disabled;
    },
    /**
     * 设置组织列表高度
     */
    setDeptHeight() {
      const height = this.choosePerson != 'organize' ? 198 : 428
      return (this.showDept && !this.showPerson) ? 398 : height
    },
    /**
     * 设置人员列表高度
     */
    setPersonHeight() {
      const height = this.choosePerson != 'organize' ? 199 : 389
      return (this.showPerson && !this.showDept) ? 399 : height
    },
    /**
     * 设置人员全选复选框状态
     */
    selectAllPerson() {
      if (!this.userData.length) {
        return false;
      }
      return this.userData.every(itemA => {
        return this.selectedData.some(itemB => {
          // 根据所传对象更新已选中的数据取消权限
          if (itemB.id === itemA.id) {
            itemA.forbidden = itemA.disabled = itemB.forbidden || false;
          }
          return itemB.id === itemA.id;
        })
      })
    },
  },
  async mounted() {
    if (this.comUse !== 'vForm') {
      await this.initSetDefaultTabList();
      // dialog页面模式 默认打开弹框
      if (this.isPage) {
        this.openDialog()
        this.getUserList(this.selectedIds);
      }
    } else {
      this.setVformDefault()
    }
    this.resetInputHeight()
  },
  watch: {
    modelValue: {
      deep: true,
      immediate: true,
      handler: async function (val) {
        if (val && val.length > 0) {
          // dialog页面模式
          if (this.isPage) { return; }
          await this.setDefault();
          if (this.comUse === 'vForm') {
            this.setVformDefault()
            if (this.visible) {
                this.getUserList(this.selectedIds);
            }
          } else {
            this.getUserList(this.selectedIds);
          }
        } else if (this.isReturnData && typeof val === "object" && val !== null) {
          this.innerValue = this.displayFormat == 'organizePath' ? val.organizeDesc || val.organize || val.name : val.mainName || val.name;
          this.selectedIds = [val.mainId || val.id];
          this.selectedData = [val];
          
          // 若modelValue为空数组且tagsList不为空，则清空tagsList
          if (Array.isArray(val) && !val.length && this.tagsList.length) {
            this.tagsList = [];
          }
        } else {
          this.innerValue = "";
          this.selectedIds = [];
          this.selectedData = [];
          this.tagsList = [];
        }
      }
    },
    multiple() {
      this.$nextTick(() => {
        this.resetInputHeight();
        this.clear();
      });
    },
    isReturnData() {
      this.$nextTick(() => {
        this.resetInputHeight();
        this.clear();
      });
    },
    selectDisabled() {
      this.$nextTick(() => {
        this.resetInputHeight();
      });
    },
    displayFormat() {
      this.setVformDefault()
      this.resetInputHeight()
    },
    authorityList() {
      this.initSetDefaultTabList();
    },
    userData(val) {
      if (val?.length) {
        setTimeout(() => {
          const scrollWrap = document.querySelector('.btn_bottom .el-tree-virtual-list');
          scrollWrap?.removeEventListener('scroll', this.handleSetScroll);
          scrollWrap?.addEventListener('scroll', this.handleSetScroll);
        }, 0);
      }
    }
  },
  methods: {
    /**
     * 表单使用设置默认展示值
     */
    setVformDefault() {
      const selectData = deepClone(this.modelValue);
      if (selectData.length > 0) {
        if (this.multiple) {
          this.innerValue = "";
          this.tagsList = selectData.map(i => this.displayFormat == 'organizePath' ? i.organizeDesc || i.organize || i.name : i.name);
          this.$nextTick(() => {
            this.resetInputHeight();
          });
        } else {
          const item = selectData[0];
          if (item) {
            this.innerValue = this.displayFormat == 'organizePath' ? item.organizeDesc || item.organize || item.name : item.name;
          }
        }
      }
    },
    /**
     * 初始化设置tab
     */
    initSetDefaultTabList() {
      // 筛选权限列表
      if (this.authorityList && this.authorityList.length) {
        this.tabList = this.defaultTabList.filter(item => {
          return this.authorityList.indexOf(item.name) != -1
        })
      } else {
        // 默认不传不显示传阅 后续可修改
        this.tabList = this.defaultTabList.filter(item => item.name != 'circulation')
      }
      // 默认选中第一个tab
      this.activeName = this.tabList[0].name
      this.setInputStyle()
      // 自动带入需请求数据
      if (this.isAutoImport && this.isReturnData) {
        this.getData();
        return;
      }
      // 初始化且无传入数据时不请求反显数据
      if (!this.visible && this.isReturnData) {
        this.getSelectedData();
        return;
      }
      this.getData();
    },
    /**
     * 设置输入框样式
     * @returns 无返回值
     */
    setInputStyle() {
      const reference = this.$refs.reference;
      if (reference && reference.$el) {
        const input = reference.$el.querySelector("input");
        this.initialInputHeight = input.getBoundingClientRect().height;
      }
      if (this.multiple) {
        this.resetInputHeight();
      }
      this.$nextTick(() => {
        if (reference && reference.$el) {
          this.inputWidth = reference.$el.getBoundingClientRect().width;
        }
      });
    },
    /**
     * 获取iconfont图标
     * @param objectType 数据类型
     * @param tag 组织类型 tag -（0组织 2单位 ）， 4项目 ， 3部门
     */
    getIconByType(objectType: string, tag?: string) {
      let data = {
        'organize': 'icon-a-bumenzuzhishu1',//组织
        'unit': 'icon-a-danweizuzhi',//单位
        'object': 'icon-xiangmu',//项目
        'user': 'icon-renyuan',//人员
        'role': 'icon-jiaose',//角色
        'post': 'icon-a-gangweilingdao',//岗位
        // 'relativePost': 'icon-xiangduigangwei',//相对岗位
        'relativeRelation': 'icon-xiangduiguanxi',//相对关系
        'group': 'icon-zu1',//组
        'circulation': 'icon-zu1',//传阅
      }
      let icon = tag == '0' ? data['unit'] : data[objectType]
      return icon
    },
    /**
     * 更改树形结构
     * @param list 树形结构数据列表
     * @param fun 回调
     * @returns 无返回值
     */
    changeTree(list, callback) {
      if (!Array.isArray(list)) {
        console.error('Input list should be an array.');
        return;
      }
      this.changeTreeDeep(list, (item) => {
        if (callback && typeof callback === 'function') {
          callback(item)
        }
        // 使用解构赋值简化属性检查和赋值
        const { mainId, mainName, organizeDesc, objectType, tag } = item;
        // 确保必要的属性存在
        item.mainId = mainId || item.id || item.userId;
        if (this.deptUrl) item.mainId = item.id || item.userId || item.deptId || mainId;
        item.mainName = mainName || item.name;
        item.sort = item.sort || 0;
        // 如果id和name不存在，则使用mainId和mainName作为默认值
        if (!item.id) item.id = item.mainId;
        if (!item.name) item.name = item.mainName;
        // 优化硬编码逻辑判断
        if (objectType === 'organize' && tag === '0' && !organizeDesc) {
          item.organizeDesc = item.name;
        }
      });
    },
    /**
     * 递归遍历树形结构数组，对数组中的每个元素执行回调函数
     * @param arr 树形结构数组
     * @param callback 回调函数，接收当前元素作为参数
     */
    changeTreeDeep(arr, callback) {
      arr.forEach((item) => {
        if (item.children && item.children.length > 0) {
          this.changeTreeDeep(item.children, callback);
        }
        if (callback && typeof callback === 'function') {
          callback(item);
        }
      })
    },
    /**
     * 获取用于回显的全部数据
     */
    async getData() {
      let allListArr = []
      // 添加组织数据
      const fetchAndProcessData = async (fetchMethod, objectType) => {
        const list = await fetchMethod();
        list.forEach(item => item.objectType = objectType);
        return list;
      };
      const conditions = [
        { fetch: this.getOrganizeData, type: 'organize', check: () => this.authorityList.includes('department') || this.choosePerson !== 'person' },
        { fetch: this.getGroupData, type: 'group', check: () => this.authorityList.includes('group') || this.choosePerson !== 'person' },
        { fetch: this.getRoleData, type: 'role', check: () => this.authorityList.includes('role') || this.choosePerson !== 'person' },
        { fetch: this.getPostData, type: 'post', check: () => this.authorityList.includes('post') || this.choosePerson !== 'person' },
        { fetch: this.getCirculationData, type: 'circulation', check: () => this.authorityList.includes('circulation') && this.choosePerson !== 'person' },
      ];
      // 默认不请求传阅数据 后续可修改
      const allPromises = conditions
        .filter(condition => (this.authorityList.length === 0 && condition.type != 'circulation') || condition.check())
        .map(condition => fetchAndProcessData(condition.fetch, condition.type));
      const allResults = await Promise.all(allPromises);
      allListArr = [].concat(...allResults);
      this.allList.push(...allListArr);
      this.getSelectedData()
    },
    /**
     * 设置tab对应类型的数据
     */
    async setTreeDataList() {
      try {
        this.loading = true;
        const dataFetchers = {
          department: () => this.getDepartmentData(''),
          group: () => this.getGroupData(),
          role: () => this.getRoleData(),
          post: () => this.getPostData(),
          // relativePost: () => this.getDepartmentData(),
          relativeRelation: () => this.getRelativeRelationData(),
          circulation: () => this.getCirculationData(),
        };
        // 使用映射来调用正确的方法，如果activeName不存在于映射中，则不执行任何操作
        if (this.activeName in dataFetchers) {
          this.treeData = await dataFetchers[this.activeName]();
        }
        this.loading = false;
        return true
      } catch (e) {
        return false
      }
    },
    /**
     * 折叠/展开树节点
     * @param id 节点ID
     * @param flag true 折叠，false 展开
     * @returns 无返回值
     */
    collapseOrExpandTreeNode(id, flag) {
      // 延迟折叠/展开节点，确保树组件已准备好
      const treeRef = this.$refs.tree;
      if (treeRef) {
        setTimeout(() => {
          const node = treeRef.getNode(id)
          flag ? treeRef.collapseNode(node) : treeRef.expandNode(node);
        }, 0);
      }
    },
    /**
     * 自定义分级加载数据
     * @param data 当前展开节点
     */
    async loadNodeData(data) {
      // 仅当全量查询(返回树状列表)并存在关键字时才加载启用分级加载
      if (this.deptUrl && this.keyword) { return; }
      if (this.activeName != 'department') { return; }
      if (data.children && data.children[0] && data.children[0].id) { return; }
      data.childLoading = true
      data.children = []
      // 重新渲染tree数据
      this.$refs.tree.setData(this.treeData);
      const list = await this.getDepartmentData(data.id)
      if (list.length) {
        data.children = list
      }
      // 重新渲染tree数据
      this.$refs.tree.setData(this.treeData);
      data.childLoading = false
    },
    /**
     * 获取tab为department 的数据
     */
    async getDepartmentData(parentId) {
      // 如果有特殊的数据逻辑处理，需在此方法内实现
      try {
        const API = this.deptUrl ? (params?: Object) => {
          return service({
            url: this.deptUrl,
            method: 'get',
            params,
          }) ;
        } : getDeptTreeParent;
        const res = await API({ parentId, deptName: this.keyword });
        const processedData = this.processDepartmentData(res.data);
        this.changeTree(processedData);
        return processedData;
      } catch (error) {
        this.$message.error('Error fetching department data:', error);
        return [];
      }
    },
    /**
     * 处理部门数据
     * @param data 部门数据
     * @returns 处理后的部门数据
     */
    processDepartmentData(data) {
      const deep = (item) => {
        if (!item.id) {
          item.id = item.mainId || item.deptId;
        }
        // 根据organizeType来设置disabled属性
        // tag -（0组织 2单位 ）， 3部门， 4项目
        switch (this.organizeType) {
          // 仅单位
          case 'unit':
            item.disabled = item.tag != 0;
            break;
          // 仅部门
          case 'department':
            item.disabled = ![2, 3].includes(Number(item.tag));
            break;
          // 仅项目
          case 'object':
            item.disabled = item.tag != 4;
            break;
          default:
            break;
        }
        // 处理选择人员的情况，设置disabled属性
        if (this.choosePerson === 'person') {
          item.disabled = true;
        }
        // 设置objectType属性
        item.objectType = 'organize';
        // 设置downFlag属性
        item.downFlag = false;
        if (item.children && item.children.length > 0) {
          item.children.forEach(deep); // 递归处理子节点
          // 仅当全量查询(返回树状列表)并存在关键字时才展开节点
          if (this.deptUrl && this.keyword) {
            this.collapseOrExpandTreeNode(item.id, false)
          }
        } else if (item.hasChild) {
          // 如果没有子节点但标记为有子节点，则设置一个禁用的占位子节点
          item.children = [{ disabled: true }];
          this.collapseOrExpandTreeNode(item.id, true)
        }
      };
      data.forEach(deep); // 处理顶层节点
      return data;
    },
    /**
     * 获取tab为role 的数据
     */
    async getRoleData() {
      // 如果有特殊的数据逻辑处理， 需在此方法内实现
      try {
        const res = await getRoleListAPI({ roleName: this.keyword })
        this.changeTree(res.data, (item) => {
          if (this.choosePerson == 'person') {
            item.disabled = true;
          }
          item.objectType = 'role';
          item.name = item.roleName;
          item.id = item.roleId;
        });
        return res.data
      } catch (e) {
        return []
      }
    },
    /**
     * 获取tab为group 的数据
     */
    async getGroupData() {
      // 如果有特殊的数据逻辑处理， 需在此方法内实现
      try {
        const res = await getGroupListAPI({ name: this.keyword, current: 1, size: 999 })
        this.changeTree(res.data.records, (item) => {
          if (this.choosePerson == 'person') {
            item.disabled = true;
          }
          item.objectType = 'group';
        });
        return res.data.records
      } catch (e) {
        return []
      }
    },
    /**
     * 获取tab为post岗位 的数据
     */
    async getPostData() {
      // 如果有特殊的数据逻辑处理， 需在此方法内实现
      try {
        const res = await getPostListAPI({ postName: this.keyword })
        this.changeTree(res.data, item => {
          if (this.choosePerson == 'person') {
            item.disabled = true;
          }
          item.name = item.postName;
          item.id = item.postId;
          item.objectType = 'post';
        });
        return res.data
      } catch (e) {
        return []
      }
    },
    /**
     * 获取tab为relativeRelation相对关系 的数据
     */
    async getRelativeRelationData() {
      // 如果有特殊的数据逻辑处理， 需在此方法内实现
      try {
        const res = await getRelativeRelationListAPI()
        this.changeTree(res.data, item => {
          // 相对关系authRadio为false时，必须选择范围才能放入备选
          // if (item.authRadio === false) {
          //   item.disabled = true;
          // }
          if (this.choosePerson == 'person') {
            item.disabled = true;
          }
          item.objectType = 'relativeRelation';
        })
        // 相对关系时，需要获取相对范围的数据 直接赋值userData数据里
        this.personLoading = true;
        this.userData = await this.getFindRelativeRangeListData();
        this.pageTotal = this.userData.length
        this.personLoading = false;
        console.log('this.modelValue', this.modelValue)
        return res.data
      } catch (e) {
        return []
      }
    },
    /**
     * 获取相对范围的数据
     */
     async getFindRelativeRangeListData() {
      try {
        const res = await getFindRelativeRangeListAPI()
        this.changeTree(res.data, item => {
          // 增加disabled属性
          item.disabled = true;
          item.objectType = 'relativeRelation';
        });
        return res.data
      } catch (e) {
        return []
      }
    },
    /**
     * 获取tab为circulation传阅组 的数据
     */
    async getCirculationData() {
      // 如果有特殊的数据逻辑处理， 需在此方法内实现
      try {
        const res = await getCirculationListAPI({ groupName: this.keyword })
        this.changeTree(res.data, (item) => {
          if (this.choosePerson == 'person') {
            item.disabled = true;
          }
          item.objectType = 'circulation';
          item.name = item.groupName;
        });
        return res.data
      } catch (e) {
        return []
      }
    },
    /**
     * 切换tab
     */
    async handleTabChange(tabName) {
      // 清空人员选择数据
      this.userData = [];
      // 清空查询条件
      this.keyword = '';
      this.personKeyword = '';
      // 重置当前选中项
      this.currentKey = ""
      // 重置全选
      this.searchAll = false;
      // 重置列表高度
      this.showDept = true;
      this.showPerson = true;
      // 请求接口 修改treeData数据
      const next = await this.setTreeDataList();
      if (next) {
        this.$nextTick(() => {
          // 参数为已选id 控制树节点选中状态
          this.selectedIds.forEach(i => this.setTreeChecked(i, true))
          // 重置树节点筛选
          this.$refs.tree.filter()
        })
      }
    },
    /**
     * 查询全部人员
     */
    handleSearchAll(val) {
      if (val) {
        this.pageCurrent = 1
        this.handleNodeClick({ id: '' })
      } else {
        this.userData = []
      }
    },
    /**
     * 选择全部人员
     */
    handleSelectAllPerson(val) {
      this.userData.forEach((item) => {
        if (val) {
          this.setTreeChecked(item.id, true);
          if (this.selectedIds.includes(item.id)) { return; }
        } else {
          if (item.forbidden) { return; }
          this.setTreeChecked(item.id, false);
        }
        this.handleCheckClickPerson(item)
      })
    },
    /**
     * 为allList提供组织数据一维数组
     */
    async getOrganizeData() {
      try {
        const res = await getDeptList();
        let list = res.data;
        if (list.length > 0) {
          list = list.map((item) => {
            return {
              ...item,
              id: item.deptId,
              type: "department"
            }
          })
        }
        this.changeTree(list);
        return list;
      } catch (e) {
        return []
      }
    },
    /**
     * 根据类型过滤树形数组
     * @param tree 树形数组
     * @param type 类型
     * @returns 过滤后的树形数组
     */
    filterTreeArray(tree, type) {
      return tree
        .filter((item) => item.objectType === type)
        .map((item) => {
          if (item.objectType !== type) {
            item = {};
          } else {
            item = Object.assign({}, item);
            if (item.children) {
              item.children = this.filterTreeArray(item.children, type);
            }
          }
          return item;
        });
    },
    /**
     * 关闭弹窗
     */
    onClose() {
      this.treeData = []
      this.userData = []
      this.searchAll = false;
      this.showPerson = true;
      this.showDept = true;
      this.activeName = this.tabList[0].name
      this.selectedRelation = null
      this.currentNodeKey = null
      this.$emit('close')
    },
    /**
     * 数据清空（初始化）
     */
    clear() {
      if (this.selectDisabled) { return };
      this.innerValue = "";
      this.selectedData = [];
      this.selectedIds = [];
      this.tagsList = [];
      this.$emit("update:modelValue", this.multiple ? [] : '')
      this.$emit("input", []);
      this.$emit("change", [], []);
    },
    /**
     * 打开弹窗
     */
    async openDialog() {
      if (this.selectDisabled) { return };
      if (this.disabled) { return };
      if (this.comUse == 'vForm') {
        await this.setInputDefault()
        await this.initSetDefaultTabList();
        this.getUserList(this.selectedIds);
      }
      await this.setDefault();
      this.keyword = "";
      this.personKeyword = "";
      this.selectedKeyword = "";
      this.currentKey = ""
      this.treeData = [];
      this.visible = true;
      if (!this.isReturnData) {
        this.getData();
      }
      await this.setTreeDataList();
    },
    /**
     * 获取人员信息
     */
    async getUserList(idList) {
      if (!(this.selectedIds && this.selectedIds.length)) { return }
      // 传入对象数组时不请求人员反显数据
      if (this.isReturnData && typeof this.modelValue !== "string") { return };
      const ids = deepClone(idList.filter(i => typeof i === 'string'))
      if (!ids.length) { return }
      const personRes = await this.getUserInfoByUserIds(ids)
      if (personRes.ok) {
        const list = personRes.data.map(item => {
          item.id = item.userId
          item.objectType = 'user'
          let deptItem = this.allList.find(i => i.id === item.deptId)
          item.deptName = item.deptName || deptItem && deptItem.name
          return item
        })
        this.allList = this.deduplication([...this.allList, ...list], 'id')
        this.setDefault()
        this.getSelectedData()
      }
    },
    /**
     * 去重数组，根据指定的key进行去重。
     * @param {Array} arr - 需要去重的数组。
     * @param {string} key - 用于去重的key。
     * @returns {Array} - 去重后的数组。
     * @throws {TypeError} - 如果arr不是数组或key不是字符串。
     */
    deduplication(arr, key) {
      if (!Array.isArray(arr)) {
        throw new TypeError('The first argument must be an array.');
      }
      if (typeof key !== 'string') {
        throw new TypeError('The second argument must be a string.');
      }
      let map = new Map();
      for (let item of arr) {
        if (!map.has(item[key])) {
          map.set(item[key], item);
        }
      }
      return [...map.values()];
    },
    /**
     * 为allList提供人员反显数据
     * @param ids 待查询人员id数组
     */
    async getUserInfoByUserIds(ids) {
      try {
        let _ids = ids.filter(i => !i.includes(':'))
        const API = (this.deptUrl && this.choosePerson != 'organize') ? getNoTenantUserInfoByIdsAPI : getUserInfoByUserIdsAPI;
        const res = await API(JSON.stringify(_ids));
        this.changeTree(res.data);
        return res;
      } catch (e) {
        return e
      }
    },
    /**
     * 左侧检索
     */
    searchClick() {
      // 重置当前选中项
      this.currentKey = '';
      if (this.keyword && (this.activeName === 'role' || this.activeName === 'post')) {
        // 树节点前台过滤
        this.$refs.tree.filter(this.keyword)
      } else {
        this.setTreeDataList()
      }
      this.$refs.tree && this.$refs.tree.filter(this.keyword);
      this.$refs.personTree && this.$refs.personTree.filter(this.keyword);
    },
    /**
     * 过滤树节点
     * @param query 过滤字段
     * @param node 树节点
     */
    filterMethod (query: string, node) {
      if (!query) { return true };
      return node.name.includes(query)
    },
    /**
     * 点击节点请求该节点下人员列表
     * @param data
     */
    async handleNodeClick(data) {
      if (data.id) { this.searchAll = false }
      // 当前tab选中类型为相对关系时, 处理点选效果 拼接
      if (this.activeName === 'relativeRelation') { 
        this.selectedRelation = null;
        this.currentNodeKey = data.id;
        this.selectedRelation = data;
        return 
      } 
    
      if (this.choosePerson == 'organize') { return }
      if (data.id && this.currentKey == data.id) {
        this.currentKey = '';
        this.userData = [];
        return;
      } else {
        this.currentKey = data.id;
      }
      this.pageTotal = 0;
      this.pageCurrent = 1;
      this.currentKey = data.id;

      this.userData = [];
      this.userSearch = '';
      this.personLoading = true;
      let res = await this.getPersonList(data.id);
      if (res.ok) {
        let list = res.data.records || res.data;
        this.pageTotal = res.data.total;
        if (list.length > 0) {
          for (let i = 0; i < list.length; i++) {
            const item = list[i];
            item.objectType = "user";
            item.orgId = data.id;
            item.id = item.userId || item.id;
            item.mainId = item.userId || item.mainId || item.id;
            item.mainName = item.name;
          };
        }
        this.userData = list;
      }
      this.personLoading = false;
    },
    /**
     * 异步获取人员列表
     * @param dataId
     */
    async getPersonList(dataId) {
      try {
        const keyNameObj = {
          'department': 'deptId',
          'role': 'roleId',
          'post': 'postId',
          'group': 'groupId',
          'circulation': 'circulationId',
        };
        const APIObj = {
          'department': this.deptUrl ? getNoTenantUserPageAPI : getPersonListAPI, //组织下人员
          'group': getUserByGroupIdAPI, //组下人员
          'role': getRoleUserListAPI, //角色下人员
          'post': getPostUserListAPI, //岗位下人员
          'circulation': getCirculationUserAPI, //传阅下人员
          // 'relativePost': getPersonListAPI, //相对岗位下人员
          // 'relativeRelation': getPersonListAPI, //相对关系下人员
        };
       
        // department(包括组织、单位、部门) group role post relativePost circulation
        const res = await APIObj[this.activeName](
          this.activeName == 'group' ? dataId : 
          this.activeName == 'circulation' ? {circulationId: dataId, mainName: this.personKeyword} : 
          {
            [keyNameObj[this.activeName]]: dataId,
            current: this.pageCurrent,
            size: 10,
            name: this.personKeyword
          });
        this.changeTree(res.data.records || res.data);
        return res;
      } catch (e) {
        this.$message.error(e.msg || "列表获取失败")
        return e
      }
    },
    /**
     * 点击展开/收起
     * @param flag 1:向上 2:向下
     */
    handleClose(flag) {
      if (flag == 1) {
        if (this.showDept && !this.showPerson) {
          this.showPerson = true
          return
        }
        this.showDept = !this.showDept
      } else if (flag == 2) {
        if (this.showPerson && !this.showDept) {
          this.showDept = true
          return
        }
        this.showPerson = !this.showPerson
      }
    },
    /**
     * 分页请求人员数据
     */
    async getPersonPagecurrentList(page) {
      if (this.personLoading) { return; }
      this.personLoading = true;
      const id = this.currentKey;
      if (page == 1) {
        this.pageCurrent = 1;
        this.userData = []
      } else {
        ++this.pageCurrent;
      }
      let res = await this.getPersonList(id);
      if (res.ok) {
        let list = res.data.records || res.data;
        this.pageTotal = res.data.total;
        if (list.length > 0) {
          for (let i = 0; i < list.length; i++) {
            const item = list[i];
            item.objectType = "user";
            item.orgId = id;
            item.id = item.userId || item.id;
            item.mainId = item.userId;
            item.mainName = item.name;
          };
        }
        this.userData = [...this.userData, ...list];
      }
      this.personLoading = false;
    },
    /**
     * 人员列表滚动事件监听
     * @param e 事件对象
     */
    handleSetScroll(e) {
      if (e.target.scrollHeight - e.target.scrollTop - e.target.clientHeight <= 10) {
        if (this.userData?.length && this.userData?.length == this.pageTotal) {
          this.$message.success("已加载全部数据")
          document.querySelector('.btn_bottom .el-tree-virtual-list')?.removeEventListener('scroll', this.handleSetScroll);
          return;
        }
        this.getPersonPagecurrentList();
      }
    },
    /**
     * 已选列表筛选
     */
    getSelectedList(key) {
      this.selectedData.forEach(item => {
        if (key) {
          if (!item.name.includes(key)) {
            item.isHide = true
          } else {
            item.isHide = false
          }
        } else {
          item.isHide = false
        }
      })
    },
    /**
     * 重置树选择状态
     */
    resetTreeChecked() {
      this.$refs.tree && this.$refs.tree.setCheckedKeys([])
      this.$refs.personTree && this.$refs.personTree.setCheckedKeys([])
    },
    /**
     * 点击复选框将节点加入已选列表（tab树勾选）
     * @param data
     * @param checkedData
     */
    async handleCheckClick(data, checkedData) {
      // 有子级 返回值为对象数组
      if (data.children && data.children.length && this.isReturnData) {
        if (this.isShowDownFlag) {
          // 是否包含级联选项 (deptUrl: UI传过来的全量查询组织树接口，默认不需要级联，可配置crossPlatformDownFlag)
          if ((this.crossPlatformDownFlag && this.deptUrl && !data.downFlag && !this.selectedData.find(i => i.id == data.id)) || !this.deptUrl && !data.downFlag && !this.selectedData.find(i => i.id == data.id)) {
            await this.$confirm('是否包含本级及下级节点', '提示', {
              confirmButtonText: '包含',
              cancelButtonText: '不包含',
              distinguishCancelAndClose: true,
              modalClass: "custom-confirm-class"
            }).then(res => {
              data.downFlag = true
            }).catch(err => { })
          }
        } else {
          data.downFlag = false
        }
      }
      this.handleSetSelectData(data); 
    },
    /**
     * tab 为相对关系时， 处理单选状态
     * @param treeData 树形结构数据
     * @param selectedId 选中的节点ID
     */
     updateTreeDataState(treeData, selectedId) {
      treeData.forEach(item => {
        item.disabled = selectedId !== null && item.id !== selectedId;
        if (item.children && item.children.length > 0) {
          this.updateTreeDataState(item.children, selectedId);
        }
      });
      this.$refs.tree.setData(this.treeData); // Force refresh tree data
    },
    
    /**
     * 人员树勾选
     * @param data
     * @param checkedData
     */
     handleCheckClickPerson(data, checkedData) {
      if (data.disabled) { return }
        this.handleSetSelectData(data);
    },
    /**
     * 相对关系-拼接数据
     * @param data
     */
    async handleNodeClickClickPerson(data) {
      // tab 为相对关系节点时，处理拼接数据
      if (this.activeName === 'relativeRelation' && this.selectedRelation) {
         // 是否包含级联选项
         if (data.authDownFlag) {
          await this.$confirm('是否包含本级及下级节点', '提示', {
            confirmButtonText: '包含',
            cancelButtonText: '不包含',
            modalClass: "custom-confirm-class"
          }).then(res => {
            data.downFlag = true
          }).catch(err => { 
            data.downFlag = false
          })
        } else {
          data.downFlag = false
        }
        let selectedItem = JSON.parse(JSON.stringify(data));
        // 相对关系节点时，处理拼接数据
        selectedItem.mainId = `${this.selectedRelation.id}@${selectedItem.id}`;
        selectedItem.name = `${this.selectedRelation.name} 的 ${selectedItem.name}`;
        this.handleSetSelectData(selectedItem);
      }
    }, 
  
    /**
   * 更新选中数据，处理树选中状态
   * @param data
   */
    handleSetSelectData(data: any) {
      // 相对关系时，处理数据
      const isRelativeRelation = data.objectType === 'relativeRelation';
      // 处理禁用取消勾选
      if (data.forbidden) {
        data.disabled = true;
      }
      const dataId = isRelativeRelation ? data.mainId : data.id;
      let item = this.selectedData.find(i => i.id === dataId);

      item 
        ? this.removeSelectedData(dataId, isRelativeRelation)
        : this.addSelectedData(data,isRelativeRelation);

      // 滚动到已选列表底部
      const anchorWrap = document.querySelector('#anchor');
      if (anchorWrap) {
        this.$nextTick(() => {
          anchorWrap.scrollIntoView({ block: 'end', behavior: 'smooth' });
        });
      }

      // dialog页面模式下，更新数据
      if (this.isPage) {
        this.confirm();
      }
    },

    /**
     * 筛选右侧选中数据
     * @param dataId
     * @param isRelativeRelation
     */
    removeSelectedData(dataId: string, isRelativeRelation: boolean) {
      this.selectedData = this.selectedData.filter(i => {
        if (i.forbidden) { i.disabled = true; }
        return isRelativeRelation ? i.mainId !== dataId : i.id !== dataId
      });
      this.selectedIds = this.selectedIds.filter(i => i !== dataId);
    },

    /**
     * 添加选中数据
     * @param data
     * @param isRelativeRelation
     */
    addSelectedData(data: any, isRelativeRelation: boolean) {
      if (this.multiple) {
        // 如果是相对关系，则检查重复
        if (isRelativeRelation) {
            const isDuplicate = this.selectedData.some(item => item.mainId === data.mainId && item.downFlag === data.downFlag);
            if (isDuplicate) {
                this.$message.warning('重复数据，不会被添加到已选列表中');
                return;
            }
        }
        this.selectedIds.push(data.id);
        this.selectedData.push(data);
      } else {
        this.selectedIds = [data.id];
        this.resetTreeChecked();
        this.setTreeChecked(data.id, true);
        this.selectedData = [data];
      }
    },

    /**
     * 清空所有选择数据
     */
    removeAll() {
      // 重置级联选项
      this.selectedData.forEach(i => i.downFlag = false);
      setTimeout(() => {
        this.resetTreeChecked();
        if (this.selectedData.some(i => i.forbidden)) {
          this.selectedData = this.selectedData.filter(i => i.forbidden);
          this.selectedIds = this.selectedData.map(i => i.id);
        } else {
          this.selectedData = [];
          this.selectedIds = [];
        }
        // dialog页面模式下，更新数据
        if (this.isPage) {
          this.confirm()
        }
      }, 0);
    },
    /**
     * 清除选择数据
     */
    removeData(item, index) {
      this.$nextTick(() => {
        item.downFlag = false; // 重置级联选项
        this.setTreeChecked(item.id, false);
        this.selectedData.splice(index, 1);
        this.selectedIds.splice(index, 1);
        // dialog页面模式下，更新数据
        if (this.isPage) {
          this.confirm()
        }
      })
    },
    /**
     * 手动设置节点选中状态
     * @param id
     * @param flag
     */
    setTreeChecked(id, flag) {
      this.$refs.tree && this.$refs.tree.setChecked(id, flag)
      this.$refs.personTree && this.$refs.personTree.setChecked(id, flag)
    },
    /**
     * 提交选择数据
     */
    async confirm() {
      // this.selectedLoading = true;
      if (this.multiple) {
        this.innerValue = "";
        this.tagsList = this.selectedData.map(item => this.displayFormat == 'organizePath' ? item.organizeDesc || item.organize || item.name : item.name).filter(item => !!item);
      } else {
        const item = this.selectedData[0];
        if (item) {
          this.innerValue = this.displayFormat == 'organizePath' ? item.organizeDesc || item.organize || item.name : item.name;
        }
      }

      console.log('this.selectedDa', this.selectedData)
      // return
      const formatData = this.handleFormatRule(deepClone(this.selectedData))
      if (this.isReturnData) {
        // defultValue类型
        this.$emit("update:modelValue", formatData)
      } else {
        const selectData = this.comUse === 'vForm' ? formatData : deepClone(this.selectedIds);
        this.$emit("update:modelValue", this.multiple ? selectData : selectData[0])
      }
      this.$emit("change", this.selectedIds, formatData);
      this.$emit("ok", this.selectedIds, formatData);
      this.selectedLoading = false;
      // dialog页面模式下，不关闭弹窗
      if (this.isPage) { return; }
      this.resetInputHeight();
      this.visible = false;
    },
    /**
     * 处理格式化规则
     * @param data 待处理的数据
     * @returns 处理后的数据
     */
    handleFormatRule(data) {
      if (this.formatRuleData && this.formatRuleData.length) {
        if (Array.isArray(data)) {
          return data.map(item => this.filterFields(item));
        } else {
          return this.filterFields(data);
        }
      } else {
        return data;
      }
    },
    /**
     * 过滤字段
     * @param item 原始数据对象
     * @returns 格式化后的数据对象，只包含 formatRuleData 中指定的字段
     */
    filterFields(item) {
      const formattedItem = {};
      this.formatRuleData.map(key => {
        if (item.hasOwnProperty(key) && item[key] != null) {
          formattedItem[key] = item[key];
        }
      })
      return formattedItem;
    },
    /**
     * 设置默认显示数据
     */
    setDefault() {
      this.setInputDefault()
      setTimeout(() => {
        // 参数为已选id 控制树节点选中状态
        this.selectedIds.forEach(i => this.setTreeChecked(i, true))
      }, 0);
    },
    /**
     * 设置输入框默认展示数据
     */
    setInputDefault() {
      if (!this.modelValue || Array.isArray(this.modelValue) && !this.modelValue.length) {
        this.innerValue = "";
        this.selectedIds = [];
        this.selectedData = [];
        this.tagsList = [];
        return;
      }
      let selectedIds;
      if (typeof this.modelValue === "string") {
        // 如果是字符串类型，则直接套数组赋值给selectedIds
        selectedIds = [this.modelValue]
      } else if (Array.isArray(this.modelValue) && (!this.modelValue.length || typeof this.modelValue[0] === "string")) {
        // 如果是空数组/数组字符串类型，则直接赋值给selectedIds
        selectedIds = this.modelValue
      } else if (typeof this.modelValue === "object" && !Array.isArray(this.modelValue)) {
        // 如果是对象类型，则将id赋值给selectedIds
        selectedIds = [this.modelValue.mainId || this.modelValue.id]
      } else {
        // 此处为数组对象类型，将ids赋值给selectedIds
        selectedIds = this.modelValue.map(i => {
          if (i.hasOwnProperty('mainId')) {
            i.id = i.mainId
          }
          return i.id
        })
      }
      this.selectedIds = deepClone(selectedIds)
      this.getSelectedData();
    },
    /**
     * 获取已选中的数据
     * @returns 无返回值，将已选中的数据赋值给this.selectedData
     */
    getSelectedData() {
      if (this.selectedIds.length === 0) {
        return;
      }
      let selectData = deepClone(this.modelValue)
      this.selectedData = this.selectedIds
        .map((record, index) => {
          const targetId = record;
          // 需传入值为对象数组
          // console.log('处理传入数据', this.modelValue[index])
          if (this.isReturnData && typeof selectData === "object" && !Array.isArray(selectData)) {
            selectData = [selectData]
          }
          if (this.isReturnData && selectData.length) {
            let item = selectData[index].item || selectData[index]
            // 处理反显
            if (item.fullName) { item.name = item.fullName; }
            if (item.mainName) { item.name = item.mainName; }
            if (item.mainId) { item.id = item.mainId }
            // 传入数据满足反显条件
            if (item.name && item.id) {
              return item
            }
          }
          const targetItem = this.allList.find((item) => item.id === targetId);
          if (!!targetItem) {
            targetItem.downFlag = selectData[index].downFlag
            return targetItem;
          }
        })
        .filter((item) => item !== undefined);
      if (this.multiple) {
        this.innerValue = "";
        this.tagsList = this.selectedData.map(i => this.displayFormat == 'organizePath' ? i.organizeDesc || i.organize || i.name : i.name);
        this.$nextTick(() => {
          this.resetInputHeight();
        });
      } else {
        const item = this.selectedData[0];
        if (item) {
          this.innerValue = this.displayFormat == 'organizePath' ? item.organizeDesc || item.organize || item.name : item.name;
        }
      }
      if (this.isAutoImport && this.selectedData.length && typeof this.modelValue === "string") {
        this.$emit("update:modelValue", this.multiple ? this.selectedData : this.selectedData[0])
        this.$emit("change", this.selectedIds, this.selectedData);
      }
    },
    /**
     * 删除input内选择数据
     * @param event
     * @param index
     */
    deleteTag(event, index) {
      this.selectedData.splice(index, 1);
      this.selectedIds.splice(index, 1);
      this.confirm();
      event.stopPropagation();
    },
    /**
     * 清空input内选择数据
     * @param event
     */
    handleClearClick(event) {
      this.selectedData = [];
      this.selectedIds = [];
      this.confirm();
      event.stopPropagation();
    },
    /**
     * 重置input高度
     */
    resetInputHeight() {
      if (this.collapseTags) { return };
      this.$nextTick(() => {
        if (!this.$refs.reference) { return };
        let input = this.$refs.reference.ref;
        const tags = this.$refs.tags;
        const tagsHeight = tags ? Math.round(tags.getBoundingClientRect().height) : 0;
        const sizeInMap = this.initialInputHeight || 30;
        input.style.height = this.selectedIds.length === 0 ? sizeInMap + "px" : Math.max( tags ? tagsHeight + (tagsHeight > sizeInMap ? 6 : 0) : 0, sizeInMap ) + "px";
      });
    },
  },
};
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>
<style lang="scss">
.custom-confirm-class {
  z-index: 3000 !important;
}
</style>